package org.webdb.jdbc.impl;

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.webdb.jdbc.JDBCException;
import org.webdb.jdbc.JDBCExecutionContext;
import org.webdb.jdbc.JDBCProvider;
import org.webdb.jdbc.JDBCUtils;

import com.healthmarketscience.sqlbuilder.DeleteQuery;
import com.healthmarketscience.sqlbuilder.InsertQuery;
import com.healthmarketscience.sqlbuilder.SqlObject;
import com.healthmarketscience.sqlbuilder.UpdateQuery;

public class JDBCProviderImpl implements JDBCProvider {

    private static final Logger logger = LoggerFactory
            .getLogger(JDBCProviderImpl.class.getSimpleName());

    private Connection connection;
    private String name;

    public JDBCProviderImpl(String name, Connection connection) {
        this.connection = connection;
        this.name = name;
    }

    public JDBCExecutionContext execute(SqlObject sqlObject) {
        Statement stmt = null;
        try {
            stmt = connection.createStatement();
            if (isUpdateQuery(sqlObject)) {
                return new JDBCExecutionContext(stmt.executeUpdate(sqlObject
                        .toString()), stmt);
            }
            return new JDBCExecutionContext(stmt.execute(sqlObject.toString()),
                    stmt);
        } catch (Exception e) {
            if (logger.isDebugEnabled())
                logger.debug(sqlObject.toString());

            throw new JDBCException(toString() + " Execute SQL", e);
        } finally {
            JDBCUtils.close(stmt);
        }
    }

    private boolean isUpdateQuery(SqlObject sqlObject) {
        if (sqlObject instanceof InsertQuery)
            return true;
        if (sqlObject instanceof UpdateQuery)
            return true;
        if (sqlObject instanceof DeleteQuery)
            return true;
        return false;
    }

    public void close() throws IOException {
        JDBCUtils.close(connection);
    }

    @Override
    public String toString() {
        return JDBCProviderImpl.class.getSimpleName() + "[" + name + "]";
    }

    public ResultSet executeQuery(SqlObject sqlObject) throws SQLException {
        return connection.createStatement().executeQuery(sqlObject.toString());
    }

}
